package com.freeme.cameraplugin.qrcodescan;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by azmohan on 17-6-24.
 */

public class QrCodeScanView extends View {
    public static final String TAG = "QrCodeScanView";
    private static final long ANIMATION_DELAY = 10L;
    private final static int DEFAULT_CONNER_COLOR = 0xFF00E5FC;
    private final static int DEFAULT_BACKGROUND_COLOR = 0x7F000000;
    private int mFrameWidth = -1;
    private int mFrameHeight = -1;
    private int mFrameMarginTop = -1;
    public static Rect sFramingRect;

    private Paint paint = new Paint();
    // 扫描线
    private Bitmap scanLight;
    // 扫描框边角颜色
    private int connerColor;
    // 扫描框边角长度
    private int connerLength;
    // 扫描框边角宽度
    private int connerWidth;
    // 扫描线移动的y
    private int scanLineTop;
    // 扫描线移动速度
    private int SCAN_VELOCITY;

    public QrCodeScanView(Context context) {
        this(context, null);
    }

    public QrCodeScanView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public QrCodeScanView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initParams(context, attrs);
    }

    /**
     * 初始化内部框的大小
     *
     * @param context
     * @param attrs
     */
    private void initParams(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.QrCodeScanView);
        // 扫描框的宽度
        mFrameWidth = (int) ta.getDimension(R.styleable.QrCodeScanView_scanRectWidth, 0);
        // 扫描框的高度
        mFrameHeight = (int) ta.getDimension(R.styleable.QrCodeScanView_scanRectHeight, 0);

        // 扫描框边角颜色
        connerColor = ta.getColor(R.styleable.QrCodeScanView_scanCornerColor, DEFAULT_CONNER_COLOR);
        // 扫描框边角长度
        connerLength = 55;
        // 扫描框边角宽度
        connerWidth = 10;

        // 扫描控件
        scanLight = BitmapFactory.decodeResource(getResources(), ta.getResourceId(R.styleable.QrCodeScanView_scanLineRes, R.mipmap.icon_scan_line));
        // 扫描速度
        SCAN_VELOCITY = 2;
        ta.recycle();
    }

    private Rect getFramingRect() {
        int width = getWidth();
        int height = getHeight();
        if (width <= 0 || height <= 0 || width <= mFrameWidth || height <= mFrameHeight) {
            return null;
        }
        int left = (width - mFrameWidth) / 2;
        int top = (height - mFrameHeight) / 2;
        Rect rect = new Rect(left, top, left + mFrameWidth, top + mFrameHeight);
        if (sFramingRect == null) {
            sFramingRect = rect;
        }
        return rect;
    }

    @Override
    public void onDraw(Canvas canvas) {
        Rect frame = getFramingRect();
        if (frame == null) {
            return;
        }
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        paint.setColor(DEFAULT_BACKGROUND_COLOR);
        canvas.drawRect(0, 0, width, frame.top, paint);
        canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);
        canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);
        canvas.drawRect(0, frame.bottom + 1, width, height, paint);

        drawFrameBounds(canvas, frame);
        drawScanLight(canvas, frame);
        postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top, frame.right, frame.bottom);
    }

    /**
     * 绘制取景框边框
     *
     * @param canvas
     * @param frame
     */
    private void drawFrameBounds(Canvas canvas, Rect frame) {
        paint.setColor(0x7FFFFFFF);
        //左
        canvas.drawLine(frame.left, frame.top, frame.left, frame.bottom - 1, paint);
        //上
        canvas.drawLine(frame.left, frame.top, frame.right - 1, frame.top, paint);
        //右
        canvas.drawLine(frame.right - 1, frame.top, frame.right - 1, frame.bottom - 1, paint);
        //下
        canvas.drawLine(frame.left, frame.bottom - 1, frame.right - 1, frame.bottom - 1, paint);

        paint.setColor(connerColor);
        paint.setStyle(Paint.Style.FILL);

        int corWidth = connerWidth;
        int corLength = connerLength;

        // 左上角
        canvas.drawRect(frame.left, frame.top, frame.left + corWidth, frame.top
                + corLength, paint);
        canvas.drawRect(frame.left, frame.top, frame.left
                + corLength, frame.top + corWidth, paint);
        // 右上角
        canvas.drawRect(frame.right - corWidth, frame.top, frame.right,
                frame.top + corLength, paint);
        canvas.drawRect(frame.right - corLength, frame.top,
                frame.right, frame.top + corWidth, paint);
        // 左下角
        canvas.drawRect(frame.left, frame.bottom - corLength,
                frame.left + corWidth, frame.bottom, paint);
        canvas.drawRect(frame.left, frame.bottom - corWidth, frame.left
                + corLength, frame.bottom, paint);
        // 右下角
        canvas.drawRect(frame.right - corWidth, frame.bottom - corLength,
                frame.right, frame.bottom, paint);
        canvas.drawRect(frame.right - corLength, frame.bottom - corWidth,
                frame.right, frame.bottom, paint);
    }

    /**
     * 绘制移动扫描线
     *
     * @param canvas
     * @param frame
     */
    private void drawScanLight(Canvas canvas, Rect frame) {
        if (scanLineTop == 0) {
            scanLineTop = frame.top;
        }
        if (scanLineTop >= frame.bottom - 30) {
            scanLineTop = frame.top;
        } else {
            scanLineTop += SCAN_VELOCITY;
        }
        Rect scanRect = new Rect(frame.left, scanLineTop, frame.right, scanLineTop + 30);
        canvas.drawBitmap(scanLight, null, scanRect, paint);
    }

    public void drawViewfinder() {
        invalidate();
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}
